package com.emotion.recognition.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;

import com.emotion.recognition.shared.Constants;
import com.google.gwt.dev.util.Preconditions;

@SuppressWarnings("serial")
public class FileUploadService extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		super.doGet(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		if (ServletFileUpload.isMultipartContent(req)) {
			FileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(factory);

			try {
				@SuppressWarnings("unchecked")
				List<FileItem> items = upload.parseRequest(req);
				String testingFileNames = "";
				String trainingFileNames = "";
				String fileNames = "";
				boolean training = true;
				for (FileItem item : items) {
					if (item.isFormField())
						continue;

					Preconditions.checkArgument(
							item.getName() != null && item.getName() != "",
							"Two items should be uploaded");

					// Save the file into a folder.
					String fileName = FilenameUtils.getName(item.getName());
					File uploadedFile = new File(Constants.ZIP_DIRECTORY,
							fileName);
					item.write(uploadedFile);

					// Unzip file and save images.
					byte[] buf = new byte[1024];
					ZipInputStream inputStream = new ZipInputStream(
							new FileInputStream(uploadedFile));

					ZipEntry entry = inputStream.getNextEntry();
					while (entry != null) {
						String entryName = entry.getName();
						FileOutputStream outputStream = new FileOutputStream(
								(training ? Constants.TRAINING_DIRECTORY
										: Constants.TESTING_DIRECTORY)
										+ "/"
										+ entryName);
						int n;
						while ((n = inputStream.read(buf, 0, 1024)) > -1) {
							outputStream.write(buf, 0, n);
						}
						outputStream.close();
						inputStream.closeEntry();
						entry = inputStream.getNextEntry();

						if (training) {
							trainingFileNames += entryName + ",";
						} else {
							testingFileNames += entryName + ",";
						}
					}
					inputStream.close();

					training = false;
				}
				fileNames = trainingFileNames.substring(0,
						trainingFileNames.length() - 1)
						+ ";"
						+ testingFileNames.substring(0,
								testingFileNames.length() - 1);

				resp.setStatus(HttpServletResponse.SC_CREATED);
				resp.setContentType("text/html");
				resp.getWriter().print(fileNames);
				resp.flushBuffer();
			} catch (Exception e) {
				e.printStackTrace();
				resp.sendError(
						HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
						"An error occurred while creating the file : "
								+ e.getMessage());
			}

		} else {
			resp.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE,
					"Request contents type is not supported by the servlet.");
		}
	}
}
